import os
import re
import configparser
import pdb
import pytest
import subprocess
import requests
from src.utils.send_wechat import SendMessage


class DownloadLibrary:

    def __init__(self, check_project):
        self.config = 'conf/mongo.ini'
        self.config_project = 'conf/project.ini'
        self.project = check_project
        self.model = ['aibs', 'lcs']
        self.user = None
        self.pwd = None
        self.path = None
        self.configInfo = dict()
        self.message = SendMessage()

    # 解析配置文件
    def get_config(self, key):
        config = configparser.ConfigParser()
        config.read(self.config)
        config_project = configparser.ConfigParser()
        config_project.read(self.config_project)
        try:
            self.user = config.get('jenkins_userInfo', f'{key}_user')
            self.pwd = config.get('jenkins_userInfo', f'{key}_pwd')
            self.path = config_project.get(f'{self.project}', 'path')
            self.configInfo['url'] = config_project.get(f'{self.project}', key)
            self.configInfo['domain'] = config.get('jenkins_userInfo', 'domain')
            libs = []
            for val in config.options(f'jenkins_{key}Library'):
                libs.append(config.get(f'jenkins_{key}Library', val))
            self.configInfo['Library'] = libs
        except Exception as e:
            raise Exception(f'{self.config} 配置文件错误!{e}')

    # 获取job下构建信息
    def getJenkinsInfo(self, url):
        try:
            response = requests.get(url, auth=(self.user, self.pwd))
            if response.status_code == 200:
                job_info = response.json()
                return job_info
            else:
                raise Exception(f'获取job下构建信息异常. Status code: {response.status_code}')
        except Exception as e:
            raise Exception(f'jenkins连接失败:{e}')

    def check_path(self):
        if not os.path.exists(self.path):
            os.makedirs(self.path)

    def replace_url_with_domain(self, url, domain):
        pattern = r'(?<=//)[^/]+'
        return re.sub(pattern, domain, url)

    # 下载库文件
    def download(self, url, name):
        try:
            self.check_path()
            command = ['curl', '-X', 'GET', '--user', f'{self.user}:{self.pwd}', '-o', f'{self.path}/{name}', f'{url}']
            result = subprocess.run(command,stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, check=True)
            if result.returncode == 0:
                print(f"{self.path}/{name} 下载成功!")
                return True
            else:
                print(f"{self.path}/{name} 下载失败!")
                return False
        except subprocess.CalledProcessError as e:
            raise Exception(f"{self.path}/{name} 下载失败! {e}")

    # 检查jenkins中库是否存在
    def check_lib(self,url, libs):
        info = []
        flag = False
        for lib in libs:
            response = requests.head(url+lib, auth=(self.user, self.pwd))
            if response.status_code != 200:
                info.append(lib.split('/')[-1])
                flag = True
        if flag:
            raise Exception(f"\n{info} 这些库在 {url}中不存在，请检查构建号! ")

    # 遍历库集合
    def start_down(self, url):
        flag = True
        libs = self.configInfo['Library']
        self.check_lib(url, libs)
        if len(libs)>0:
            for lib in libs:
                if not self.download(url+lib,lib.split('/')[-1]):
                    flag = False
            if flag:
                return True
        return False

    # 下载库模块总入口
    def run_down(self, value):
        vals = value.split('-')
        for i,val in enumerate(vals):
            url = ''
            key = self.model[i]
            if val != '':
                try:
                    self.get_config(key)
                    job_info = self.getJenkinsInfo(f"{self.configInfo['url']}/api/json")
                    if val != 'new':
                        for info in job_info['builds']:
                            if info['number'] == int(val):
                                if self.getJenkinsInfo(f"{self.configInfo['url']}/{int(val)}/api/json")['result'] == 'SUCCESS':
                                    url = info['url']
                                else:
                                    raise Exception(f"{info['url']} 这个库构建失败")
                    else:
                        info = job_info['lastSuccessfulBuild']
                        val = info['number']
                        url = info['url']
                    if key == 'aibs':
                        url = self.replace_url_with_domain(url, self.configInfo['domain'])
                    if self.start_down(url):
                        print(f'{url} 下载成功!')
                except Exception as e:
                    print(f"下载库异常! {e}")
                    raise e
